using System;
using System.IO;
using TextMenus;

namespace CardsEngine.Poker.PokerTestKit
{
    /// <summary>
    /// A simple console I/O handler
    /// </summary>
	internal class TextBasedActionHandler
	{
        private class ActionMenu: TextMenu
        {
            public static readonly MenuOption CheckOption = new MenuOption("Check", CheckCallback);
            public static readonly MenuOption CallOption = new MenuOption("Call", CallCallback);
            public static readonly MenuOption FoldOption = new MenuOption("Fold", FoldCallback);
            public static readonly MenuOption BetRaiseOption = new MenuOption("Bet/Raise", BetRaiseCallback);

            private static void BetRaiseCallback(MenuInputInfo obj)
            {
                throw new NotImplementedException();
            }

            private static void FoldCallback(MenuInputInfo obj)
            {
                throw new NotImplementedException();
            }

            private static void CallCallback(MenuInputInfo obj)
            {
                throw new NotImplementedException();
            }

            private static void CheckCallback(MenuInputInfo obj)
            {
 	            throw new NotImplementedException();
            }

            public ActionMenu()
                : base()
            {
                AddOptions();
            }

            private void AddOptions()
            {
                AddMenuOption(CheckOption);
                AddMenuOption(CallOption);
                AddMenuOption(FoldOption);
                AddMenuOption(BetRaiseOption);
            }
        }

        private ActionMenu menu;

		private TextReader reader;
		private TextWriter writer;

		public TextBasedActionHandler ()
		{
			reader = Console.In;
			writer = Console.Out;
            InitializeInstance();
		}

		public TextBasedActionHandler (TextReader _in, TextWriter _out)
		{
			reader = _in;
			writer = _out;
            InitializeInstance();
        }

        private void InitializeInstance()
        {
            menu = new ActionMenu();
            //menu.BeforeMenuOptionChosen += menu_BeforeMenuOptionChosen;
            //menu.AfterMenuOptionChosen += menu_AfterMenuOptionChosen;
        }

        private PokerGame.ImmutablePokerAction GetPokerAction(PokerGame.MutablePokerAction action)
        {
            MenuInputInfo input;

            // Loop until the user gives us good input
            getinput:

            do
            {
                input = menu.RunOnce(reader, writer);
            } while (input == null);

            if (input.SelectedOption == ActionMenu.CheckOption)
                action.SetSimple(PokerGame.PokerActionType.CHECK);
            else if (input.SelectedOption == ActionMenu.CallOption)
                action.SetSimple(PokerGame.PokerActionType.CALL);
            else if (input.SelectedOption == ActionMenu.FoldOption)
                action.SetSimple(PokerGame.PokerActionType.FOLD);
            else if (input.SelectedOption == ActionMenu.BetRaiseOption)
            {
                if (input.Args.Length < 2)
                    goto getinput;

                try
                {
                    action.SetSimple(PokerGame.PokerActionType.BET_OR_RAISE, decimal.Parse(input.Words[1]));
                }
                catch (FormatException)
                {
                    goto getinput;
                }
            }

            return action;
        }

		private void PromptPokerAction (PokerGame.PokerAction action)
		{
			writer.WriteLine("{0}: place your bet", action.Actor.Owner.Name);
			writer.WriteLine("Current amount needed to call is: {0}", action.Game.GetAmountNeededToCall(action.Actor));
		}

		public PokerGame.ImmutablePokerAction GetPlayerAction(PokerGame.MutablePokerAction action)
		{
            PokerGame.ImmutablePokerAction result;

			throw new NotImplementedException();

			PromptPokerAction(action);

            result = GetPokerAction(action);

			// Todo - obtain the user's choice and call action.SetSimple or action.SetStrict
			//action.SetSimple( ... )

			//return action;
		}
	}
}

